using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace BouncinBall.Indicators
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class LocatorArrow : Microsoft.Xna.Framework.DrawableGameComponent
    {
        public const string GREEN_TEXTURE = "arrow_green_32x32";
        public const string YELLOW_TEXTURE = "arrow_yellow_32x32";
        public const string RED_TEXTURE = "arrow_red_32x32";

        private const float INITIAL_SCALE = 0.5F;
        private const float NEAR_SCALE = 1.0F;
        private const float NEAR2_SCALE = 1.4F;
        private const float MED_SCALE = 1.8F;
        private const float MED2_SCALE = 2.0F;
        private const float FAR_SCALE = 2.5F;
        private const float FAR2_SCALE = 3F;

        private const float NEAR = 0.005F;//0.1F;
        private const float NEAR2 = 0.01F;//0.5F;
        private const float MED = 0.015F;//1.0F;
        private const float MED2 = 0.02F;//1.5F;
        private const float FAR = 0.025F;//2.0F;
        private const float FAR2 = 0.03F;//2.5F;

        private bool _grow;

        public bool visible { get; set; }

        private Texture2D _texture;
        private string _textureString;

        private BouncingBallGame.ArrowOrient _orient;
        private Vector2 _screenPosition;
        private Vector2 _ballPos;
        private float _spriteScale;
        private float _distanceScale;

        public float Depth { get; set; }
        public Utility.Position Position { get; set; }

        public LocatorArrow(Game game)
            : base(game)
        {
            Position = new Utility.Position();
            // TODO: Construct any child components here
        }

        public LocatorArrow(Game game, BouncingBallGame.ArrowOrient orientation)
            : this(game)
        {
            if (orientation == BouncingBallGame.ArrowOrient.left)
                Position = new Utility.Position(-0.04F, -0.015F, 1);
            if (orientation == BouncingBallGame.ArrowOrient.right)
                Position = new Utility.Position(0.04F, -0.015F, 1);
            if (orientation == BouncingBallGame.ArrowOrient.up)
                Position = new Utility.Position(0, -.067F, 1);
            if (orientation == BouncingBallGame.ArrowOrient.down)
                Position = new Utility.Position(0, .039F, 1);

            Depth = BouncingBallGame.ARROW_DEPTH;
            _orient = orientation;
            _textureString = GREEN_TEXTURE;
            _grow = true;
            _spriteScale = INITIAL_SCALE;
            _distanceScale = INITIAL_SCALE;
            visible = true;
        }

        private void setDistanceScale(float distance)
        {
            if (distance <= 0)
                visible = false;
            else
            {
                visible = true;
                if (distance > 0F && distance <= NEAR)
                {
                    _texture = this.Game.Content.Load<Texture2D>(GREEN_TEXTURE);
                    _distanceScale = INITIAL_SCALE;
                }
                else if (distance > NEAR && distance <= NEAR2)
                {
                    _texture = this.Game.Content.Load<Texture2D>(GREEN_TEXTURE);
                    _distanceScale = NEAR_SCALE;
                }
                else if (distance > NEAR2 && distance <= MED)
                {
                    _texture = this.Game.Content.Load<Texture2D>(YELLOW_TEXTURE);
                    _distanceScale = NEAR2_SCALE;
                }
                else if (distance > MED && distance <= MED2)
                {
                    _texture = this.Game.Content.Load<Texture2D>(YELLOW_TEXTURE);
                    _distanceScale = MED_SCALE;
                }
                else if (distance > MED2 && distance <= FAR)
                {
                    _texture = this.Game.Content.Load<Texture2D>(RED_TEXTURE);
                    _distanceScale = MED2_SCALE;
                }
                else if (distance > FAR && distance <= FAR2)
                {
                    _texture = this.Game.Content.Load<Texture2D>(RED_TEXTURE);
                    _distanceScale = FAR_SCALE;
                }
                else
                {
                    _texture = this.Game.Content.Load<Texture2D>(RED_TEXTURE);
                    _distanceScale = FAR2_SCALE;
                }

            }

        }

        public void SetBallRelativePosition(Vector2 pos) {
            _ballPos = pos;

            switch (_orient)
            {
                case BouncingBallGame.ArrowOrient.left:
                    setDistanceScale(-pos.X);
                    break;
                case BouncingBallGame.ArrowOrient.right:
                    setDistanceScale(pos.X);
                    break;
                case BouncingBallGame.ArrowOrient.up:
                    setDistanceScale(-pos.Y);
                    break;
                case BouncingBallGame.ArrowOrient.down:
                    setDistanceScale(pos.Y);
                    break;

            }
        }

        public void SetPosition(Utility.Position pos)
        {
            //System.Diagnostics.Debug.WriteLine(((BouncinBall.BouncingBallGame)Game).ScreenWidthPixels);
            //System.Diagnostics.Debug.WriteLine(((BouncinBall.BouncingBallGame)Game).ScreenHeightPixels);
            if(_orient == BouncingBallGame.ArrowOrient.left)
                _screenPosition = pos.LateralPosition //position offset in meters
                * (int)((BouncinBall.BouncingBallGame)Game).PixelsPerMeter //convert to pixels
                + new Vector2(((BouncinBall.BouncingBallGame)Game).ScreenWidthPixels / 2.0F, ((BouncinBall.BouncingBallGame)Game).ScreenHeightPixels / 2.0F)
                + new Vector2(0 , _texture.Width * _spriteScale / 2.0F);
            if (_orient == BouncingBallGame.ArrowOrient.right)
                _screenPosition = pos.LateralPosition //position offset in meters
                * (int)((BouncinBall.BouncingBallGame)Game).PixelsPerMeter //convert to pixels
                + new Vector2(((BouncinBall.BouncingBallGame)Game).ScreenWidthPixels / 2.0F, ((BouncinBall.BouncingBallGame)Game).ScreenHeightPixels / 2.0F)
                - new Vector2(0, _texture.Width * _spriteScale / 2.0F);
            if (_orient == BouncingBallGame.ArrowOrient.up)
                _screenPosition = pos.LateralPosition //position offset in meters
                * (int)((BouncinBall.BouncingBallGame)Game).PixelsPerMeter //convert to pixels
                + new Vector2(((BouncinBall.BouncingBallGame)Game).ScreenWidthPixels / 2.0F, ((BouncinBall.BouncingBallGame)Game).ScreenHeightPixels / 2.0F)
                - new Vector2(_texture.Width * _spriteScale / 2.0F, 0);
            if (_orient == BouncingBallGame.ArrowOrient.down)
                _screenPosition = pos.LateralPosition //position offset in meters
                * (int)((BouncinBall.BouncingBallGame)Game).PixelsPerMeter //convert to pixels
                + new Vector2(((BouncinBall.BouncingBallGame)Game).ScreenWidthPixels / 2.0F, ((BouncinBall.BouncingBallGame)Game).ScreenHeightPixels / 2.0F)
                + new Vector2(_texture.Width * _spriteScale / 2.0F, 0);
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();

            _texture = this.Game.Content.Load<Texture2D>(_textureString);

            SetPosition(Position);
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here

            if (visible)
            {

                if (_spriteScale < (_distanceScale * 1.2) && _spriteScale >= _distanceScale)
                {
                    if (_grow)
                    {
                        _spriteScale *= 1.01F;
                        SetPosition(Position);
                    }
                    else
                    {
                        _spriteScale /= 1.01F;
                        SetPosition(Position);
                    }
                }
                else
                {
                    if (_spriteScale >= _distanceScale * 1.2F)
                    {
                        _spriteScale = _distanceScale * 1.19F;
                        _grow = false;
                    }
                    else
                    {
                        _spriteScale = _distanceScale;
                        _grow = true;
                    }
                }
            }

            System.Diagnostics.Debug.WriteLine(_spriteScale);
            base.Update(gameTime);
        }

        public override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
        {
            base.Draw(gameTime);


            if (visible)
            {
                //_spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
                if (_orient == BouncingBallGame.ArrowOrient.up)
                    ((BouncingBallGame)Game).SpriteBatch.Draw(_texture, _screenPosition, null, Color.White, 0, Vector2.Zero, _spriteScale, SpriteEffects.None, Depth);
                if (_orient == BouncingBallGame.ArrowOrient.left)
                    ((BouncingBallGame)Game).SpriteBatch.Draw(_texture, _screenPosition, null, Color.White, 3.14F * 3 / 2, Vector2.Zero, _spriteScale, SpriteEffects.None, Depth);
                if (_orient == BouncingBallGame.ArrowOrient.right)
                    ((BouncingBallGame)Game).SpriteBatch.Draw(_texture, _screenPosition, null, Color.White, 3.14F / 2, Vector2.Zero, _spriteScale, SpriteEffects.None, Depth);
                if (_orient == BouncingBallGame.ArrowOrient.down)
                    ((BouncingBallGame)Game).SpriteBatch.Draw(_texture, _screenPosition, null, Color.White, 3.14F, Vector2.Zero, _spriteScale, SpriteEffects.None, Depth);
                //_spriteBatch.End();
            }
        }
    }
}
